package amzn.partner;

import java.io.ByteArrayInputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import amzn.partner.core.amznclient;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TextView;

public class AmazonPartnerNetActivity extends Activity {
    private amznclient client;
    private String username = "";
    private String password = "";
    
    private ProgressDialog progressDialog;
    
    public static final String PREFS_NAME = "AmazonPartnerNetPrefs";
    private SharedPreferences settings;
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // set the title for this app
        this.setTitle("Amazon PartnerNet");
        
        // get the master layout
        this.setContentView(R.layout.main);
        
        // instanciate the shared prefs
        settings = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        
        // define the handler and actions for the update button
        final AmazonPartnerNetActivity tActivity = this;
        final Button updateButton = (Button) findViewById(R.id.UpdateButton);
        updateButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click
            	tActivity.showUpdateDialog();
            }
        });
        
        // make the app exit on exit button click
        final Button exitButton = (Button) findViewById(R.id.ExitButton);
        exitButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click
            	tActivity.finish();
            }
        });
        
        // show the login dialog
        this.showLoginDialog();
    }
    
    /* show the update dialog with the time frame selection */
    private void showUpdateDialog(){
    	final AmazonPartnerNetActivity tActivity = this;
    	LayoutInflater factory = LayoutInflater.from(this);
        
    	final View dateDialogView = factory.inflate(R.layout.datedialog, null);   
        final DatePicker ReportingFromDatePicker = (DatePicker)dateDialogView
        							.findViewById(R.id.ReportingFromDatePicker);
        final DatePicker ReportingToDatePicker = (DatePicker)dateDialogView
        							.findViewById(R.id.ReportingToDatePicker);
    	
        AlertDialog dateDialog = new AlertDialog.Builder(AmazonPartnerNetActivity.this)
        .setTitle("Set Reporting Timeframe")
        .setView(dateDialogView)
        .setPositiveButton("Apply", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                	dialog.cancel();
                	Calendar reportFrom = Calendar.getInstance();
                	reportFrom.set(ReportingFromDatePicker.getYear(), 
                			ReportingFromDatePicker.getMonth(), 
                			ReportingFromDatePicker.getDayOfMonth());
                	Calendar reportTo = Calendar.getInstance();
                	reportTo.set(ReportingToDatePicker.getYear(), 
                			ReportingToDatePicker.getMonth(), 
                			ReportingToDatePicker.getDayOfMonth());
                	
                	// instanciate the client
                	tActivity.client = new amznclient(tActivity);
                	tActivity.client.setUsername(tActivity.username);
                	tActivity.client.setPassword(tActivity.password);
                	tActivity.client.setReportingTimeframe(reportFrom, reportTo);
                	tActivity.updateData();
                }
            })
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                	dialog.cancel();
                }
            })
        .create();
    
        dateDialog.show();
    }
    
    /** shows the login dialog that 
     * 	asks for the credentials **/
    private void showLoginDialog(){   	
    	LayoutInflater factory = LayoutInflater.from(this);
    	
        final View loginDialogView = factory.inflate(R.layout.logindialog, null);
        final EditText usernameInput = (EditText) loginDialogView.findViewById(R.id.UsernameEditText);
        final EditText passwordInput = (EditText) loginDialogView.findViewById(R.id.PasswordEditText);
        final CheckBox StoreCredentialsLocallyCheckBox = (CheckBox)loginDialogView.findViewById
        													(R.id.StoreCredentialsLocallyCheckBox);
        
        final amznclient tClient = this.client;
        final AmazonPartnerNetActivity tActivity = this;
        
        // check if authentication storage is activated
        if(this.settings.getBoolean("AmznPartnerAuthSave", false)){
        	// preset username and password as stored and also activate the checkbox
        	usernameInput.setText(this.settings.getString("AmznPartnerAuthUser", ""));
        	passwordInput.setText(this.settings.getString("AmznPartnerAuthPass", ""));
        	StoreCredentialsLocallyCheckBox.setChecked(true);
        }
        
        AlertDialog loginDialog = new AlertDialog.Builder(AmazonPartnerNetActivity.this)
            .setTitle("Amazon PartnerNet Login")
            .setView(loginDialogView)
            .setPositiveButton("Login", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                    	String usernameValue = usernameInput.getText().toString();
                    	String passwordValue = passwordInput.getText().toString();
                    	
                    	if(usernameValue.length() > 0 && passwordValue.length() > 0){
                    		// pass the credentials to the client
                    		tActivity.username = usernameValue;
                    		tActivity.password = passwordValue;
                    		
                    		// check if the user wants to store the data
                    		if(StoreCredentialsLocallyCheckBox.isChecked()){
                    			// store the user data
                    			SharedPreferences.Editor editor = tActivity.settings.edit();
                    			editor.putString("AmznPartnerAuthUser", usernameValue);
                    			editor.putString("AmznPartnerAuthPass", passwordValue);
                    			editor.putBoolean("AmznPartnerAuthSave", true);
                    			editor.commit();
                    		}else{
                    			// delete any existing user data
                    			SharedPreferences.Editor editor = tActivity.settings.edit();
                    			editor.remove("AmznPartnerAuthUser");
                    			editor.remove("AmznPartnerAuthPass");
                    			editor.putBoolean("AmznPartnerAuthSave", false);
                    			editor.commit();
                    		}
                        	
                        	// close the dialog
                        	dialog.cancel();
                        	
                        	// instanciate the client
                        	tActivity.client = new amznclient(tActivity);
                        	tActivity.client.setUsername(tActivity.username);
                        	tActivity.client.setPassword(tActivity.password);
                        	
                        	// start the download of the data to display
                        	tActivity.updateData();	
                    	}else{
                    		// display an error message
                    		AlertDialog.Builder builder = new AlertDialog.Builder(tActivity);
                    		builder.setMessage("Please provide username and password")
                    		       .setCancelable(false)
                    		       .setTitle("Insufficient information")
                    		       .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    		           public void onClick(DialogInterface dialog, int id) {
                    		        	   tActivity.showLoginDialog();
                    		           }
                    		       });
                    		AlertDialog alert = builder.create();
                    		alert.show();
                    	}
                    }
                })
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                    	AmazonPartnerNetActivity.this.finish();
                    }
                })
            .create();
        
        loginDialog.show();
    }
    
    // call the update data to fetch data using the client
    private void updateData(){    	
    	this.progressDialog = ProgressDialog.show(AmazonPartnerNetActivity.this, 
    									"Amazon PartnerNet", "Logging in & fetching data", true);
    	this.client.execute();
    }
    
    // display the fetched data on the screen
    public void updateDataReady(String fetchedData){
    	// first of all cancel the progress dialog
    	this.progressDialog.cancel();
    	
    	// display an error when the login failed
    	if(fetchedData.equals("LOGIN_FAILED")){
    		final AmazonPartnerNetActivity tActivity = this;
    		// display an error message
    		AlertDialog.Builder builder = new AlertDialog.Builder(this);
    		builder.setMessage("The username or password provided is invalid.")
    		       .setCancelable(false)
    		       .setTitle("Login failed")
    		       .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
    		           public void onClick(DialogInterface dialog, int id) {
    		        	   // cancel the thread first so that
    		        	   // the user can retry logging in
    		        	   tActivity.client.cancel(true);
    		        	   // show the login dialog once more
    		        	   tActivity.showLoginDialog();
    		           }
    		       });
    		AlertDialog alert = builder.create();
    		alert.show();
    	}else{
    		// continue processing
    		if(fetchedData.equals("DATA_DOWNLOAD_FAILED")==true || fetchedData.length() == 0){
        		final AmazonPartnerNetActivity tActivity = this;
        		// display an error message
        		AlertDialog.Builder builder = new AlertDialog.Builder(this);
        		builder.setMessage("Error fetching data: Server did not return expected data")
        		       .setCancelable(false)
        		       .setTitle("Data retrieval failed")
        		       .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        		           public void onClick(DialogInterface dialog, int id) {
        		        	   // cancel the thread first so that
        		        	   // the user can retry logging in
        		        	   tActivity.client.cancel(true);
        		        	   // show the login dialog once more
        		        	   tActivity.showLoginDialog();
        		           }
        		       });
        		AlertDialog alert = builder.create();
        		alert.show();   			
    		}else{
    			// process and show the data
    			this.updateUi(fetchedData);
    		}
    	}
    }
    
    // update the ui with the new data
    private void updateUi(String XmlData){
    	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    	try {
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document doc = builder.parse(new ByteArrayInputStream(XmlData.getBytes()));
			TextView ShipmentTotalUnitsTextView = (TextView)this.findViewById(R.id.ShipmentTotalUnitsTextView);
			TextView ShipmentTotalRevenueTextView = (TextView)this.findViewById(R.id.ShipmentTotalRevenueTextView);
			TextView ShipmentTotalEarningsTextView = (TextView)this.findViewById(R.id.ShipmentTotalEarningsTextView);
			
			NodeList shipmentTotalXml = doc.getElementsByTagName("ShipmentTotals");
			NodeList shipmentTotalList = shipmentTotalXml.item(0).getChildNodes();
			for(int n=0; n<shipmentTotalList.getLength(); n++){
				if(shipmentTotalList.item(n).getNodeName().equals("Units")){
					String shippedUnitsValue = shipmentTotalList.item(n)
										.getChildNodes().item(0).getNodeValue();
					ShipmentTotalUnitsTextView.setText(shippedUnitsValue);
				}if(shipmentTotalList.item(n).getNodeName().equals("Revenue")){
					ShipmentTotalRevenueTextView.setText(shipmentTotalList.item(n)
										.getChildNodes().item(0).getNodeValue()+" €");
				}if(shipmentTotalList.item(n).getNodeName().equals("Earnings")){
					ShipmentTotalEarningsTextView.setText(shipmentTotalList.item(n)
										.getChildNodes().item(0).getNodeValue()+" €");
				}
			}
			
			TextView ReturnedTotalUnitsTextView = (TextView)this.findViewById(R.id.ReturnedTotalUnitsTextView);
			TextView ReturnedTotalRevenueTextView = (TextView)this.findViewById(R.id.ReturnedTotalRevenueTextView);
			TextView ReturnedTotalEarningsTextView = (TextView)this.findViewById(R.id.ReturnedTotalEarningsTextView);
			
			NodeList returnedTotalXml = doc.getElementsByTagName("ReturnedTotals");
			NodeList returnedTotalList = returnedTotalXml.item(0).getChildNodes();
			for(int n=0; n<returnedTotalList.getLength(); n++){
				if(shipmentTotalList.item(n).getNodeName().equals("Units")){
					ReturnedTotalUnitsTextView.setText(returnedTotalList.item(n)
										.getChildNodes().item(0).getNodeValue());
				}if(shipmentTotalList.item(n).getNodeName().equals("Revenue")){
					ReturnedTotalRevenueTextView.setText(returnedTotalList.item(n)
										.getChildNodes().item(0).getNodeValue()+" €");
				}if(shipmentTotalList.item(n).getNodeName().equals("Earnings")){
					ReturnedTotalEarningsTextView.setText(returnedTotalList.item(n)
										.getChildNodes().item(0).getNodeValue()+" €");
				}
			}
			
			TextView ReferralFeeTotalUnitsTextView = (TextView)this.findViewById(R.id.ReferralFeeTotalUnitsTextView);
			TextView ReferralFeeTotalRevenueTextView = (TextView)this.findViewById(R.id.ReferralFeeTotalRevenueTextView);
			TextView ReferralFeeTotalEarningsTextView = (TextView)this.findViewById(R.id.ReferralFeeTotalEarningsTextView);
			
			NodeList referalTotalXml = doc.getElementsByTagName("ReferralFeeTotals");
			NodeList referalTotalList = referalTotalXml.item(0).getChildNodes();
			for(int n=0; n<returnedTotalList.getLength(); n++){
				if(shipmentTotalList.item(n).getNodeName().equals("Units")){
					ReferralFeeTotalUnitsTextView.setText(referalTotalList.item(n)
										.getChildNodes().item(0).getNodeValue());
				}if(shipmentTotalList.item(n).getNodeName().equals("Revenue")){
					ReferralFeeTotalRevenueTextView.setText(referalTotalList.item(n)
										.getChildNodes().item(0).getNodeValue()+" €");
				}if(shipmentTotalList.item(n).getNodeName().equals("Earnings")){
					ReferralFeeTotalEarningsTextView.setText(referalTotalList.item(n)
										.getChildNodes().item(0).getNodeValue()+" €");
				}
			}
			
			TextView ReportingDateTextView = (TextView)this.findViewById(R.id.ReportingDateTextView);
			ArrayList<Calendar> reportingDate = this.client.getReportingTimeframe();
			SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
			ReportingDateTextView.setText(dateFormat.format(reportingDate.get(0).getTime())
							+ " - " + dateFormat.format(reportingDate.get(1).getTime()));
		} catch (Exception e) {
			// throw an error here...
			Log.e("APN", e.getMessage());
		}
    }
}